import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Flying Turtle from Super Mario Bros.
 */
public class Turtle  extends Mover implements Runnable
{
    private GreenfootImage[] walkLeft;
    private GreenfootImage[] walkRight;
    private GreenfootImage[] flyLeft ;
    private GreenfootImage[] flyRight ;
    private GreenfootImage[] death ;
    private boolean invincible;
    private long timeStartInvincible;
    
    private retroWorld theWorld;
    
    private int walkCounter;
    private int vSpeed ;
    private int acceleration;
    private int halfImg;
    private int jumpStrength;
    private int halfImgWidth;
    private double moveAmount ;
    
    private boolean isFlying ;
    private boolean isWalking ;
    private boolean isFacingRight;
    
    private boolean alive;
    
    Simon simon;
    Health health;

    private volatile Thread t;
    
    /** Constructor, initialize a new Turtle and variables
     * 
     */
    public Turtle()
    {
        
        alive=true;
        
        walkLeft = new GreenfootImage[2];
        walkRight = new GreenfootImage[2];
        flyLeft = new GreenfootImage[2];
        flyRight = new GreenfootImage[2];
        death = new GreenfootImage[2];
        invincible=false;
    
     
        walkCounter = 0;
        vSpeed = 0;
        acceleration = 1;
        halfImg = getImage().getHeight()/2;
        halfImgWidth = getImage().getWidth()/2;
        jumpStrength = 10;
        moveAmount = -2.0;
    
        isFlying = true;
        isWalking = false;
        isFacingRight = false;
    
    
    
        
        
        walkLeft[0] = new GreenfootImage("turtleWalkLeft1.png");
        walkLeft[1] = new GreenfootImage("turtleWalkLeft2.png");
        walkRight[0] = new GreenfootImage("turtleWalkRight1.png");
        walkRight[1] = new GreenfootImage("turtleWalkRight2.png");
        flyLeft[0] = new GreenfootImage("turtleFlyLeft1.png");
        flyLeft[1] = new GreenfootImage("turtleFlyLeft2.png");
        flyRight[0] = new GreenfootImage("turtleFlyRight1.png");
        flyRight[1] = new GreenfootImage("turtleFlyRight2.png");
        death[0] = new GreenfootImage("turtleDeath1.png");
        death[1] = new GreenfootImage("turtleDeath2.png");
        
       
    }
    
    public void addedToWorld(World world)
    {
        theWorld = (retroWorld)world;
        
         simon = theWorld.getSimon();
        health = theWorld.getHealth();
        t = new Thread(this);
        t.start();
    }    
    
    public void run()
    {
        while(alive)
        {
            if(!alive)
               break;
     
            if (alive)   
                fall();
            if (alive)    
                checkCollision();
            
            if(alive)    
                moveAround();
            if(alive)    
                cycleImage();
            if(alive)    
                checkInvincible();
            
            if (alive)
                //If the turtle reaches the end of the screen, go the other way
                if (isFacingRight && getX() >= (theWorld.worldWidth - 10))
                    isFacingRight = false;
            if (alive)
                if (!isFacingRight && getX() <= 0)
                    removeFromWorld();
                //isFacingRight = true;
            if (alive)    
                //Also if the Turtle hits a wall or pipe, change direction
                if (isFacingRight && theWorld.isGround(getX() + halfImgWidth, getY()))
                    isFacingRight = false;
            if (alive)
                if (!isFacingRight && theWorld.isGround(getX() - halfImgWidth, getY()))
                    isFacingRight = true;
            
            if (alive)
                if (getY() > (theWorld.worldHeight - 60))
                    removeFromWorld();
                    
              
                      
                      //Move left (Can't go through walls or pipes)
        if (alive/*&&Greenfoot.isKeyDown("d")*/&&theWorld.canScrollWorld(1) )
        {
           
               if(theWorld.isGround(getX(), getY()))
                while(alive && theWorld.isGround(getX(), getY())){
                    setLocation(getX()-2,getY());
                    if(getX()<10)
                     removeFromWorld();
                    
                }
                      
                      
              
            }  
            
            try {
                t.sleep(20);
            } catch (InterruptedException e) {}            
        }
    }
    
    /** Make the Turtle invincible for half a second after being hit
     * 
     */
    private void checkInvincible(){
        if(!invincible)
            return;
        
        long time=System.currentTimeMillis();
        
        if((time-timeStartInvincible) > 500)
            invincible=false;
    }
    
    /** Fall towards the ground
     * 
     */
    private void fall()
    {
        vSpeed = vSpeed + acceleration;
        
        //detect collision with ground pixel by pixel
        for (int i = 0; i <= vSpeed; i++)
        {
            if (alive && theWorld.isGround(getX(), getY() + halfImg + i))
            {
                vSpeed = 0;
                setLocation(getX(), getY() + i);
            }

        }
        
        setLocation (getX(), (getY() + vSpeed));
    }
    
    /** Handles collision detection between Simon and Turtle appropriately
     * 
     */
    private synchronized void checkCollision()
    {
        if (intersects(simon))
        {
            if (simon.isCurrentlyWhipping() && !invincible)
                takeDamage();
            else if (simon.isCurrentlyWhipping() == false){
                health.takeDamage();
            
            }
        }
    }
    
    /** Move Around the World
     * 
     */
    private void moveAround()
    {
        //Always move across the screen
        if (isFacingRight)
            move(-moveAmount);
        else
            move(moveAmount);
            
        //and continue jumping if flying
        if (!alive)
            return;
        if (isFlying && (theWorld.isGround(getX(), getY() + halfImg)))
            jump();
    }
    
    private void cycleImage()
    {
        //if (getX() % 10 == 0)
        {
            if (isFlying && isFacingRight)
                setImage(flyRight[walkCounter % 2]);
            if (isFlying && !isFacingRight)
                setImage(flyLeft[walkCounter % 2]); 
            if (!isFlying && isFacingRight)
                setImage(walkRight[walkCounter % 2]);
            if (!isFlying && !isFacingRight)
                setImage(walkLeft[walkCounter % 2]);
                
            walkCounter++;
        }        
    }
    
    private void jump()
    {                
        vSpeed = -jumpStrength;
        fall();
    }
    
    public void removeFromWorld()
    {
        try {
            
            setImage(death[0]);
            t.sleep(100);
            setImage(death[1]);
            t.sleep(100);
            
        } catch (InterruptedException e) {}
          alive=false;
        theWorld.removeObject(this);
    }
    
    //After first hit, walk, second hit turtle is dead
    private void takeDamage()
    {
        
        if (isFlying)
        {
            invincible=true;
            timeStartInvincible=System.currentTimeMillis();
            isFlying = false;
            isWalking = true;
            return;
        }
        
        if (isWalking){
            t=null;
            alive=false;
            removeFromWorld();
        }
    }
}
